#include "Matrix4x4.h"
#include "Vector4.h"
#include <cassert>

namespace DYMath
{
	Matrix4x4::Matrix4x4()
	{
		value[0] = col_type(0, 0, 0, 0);
		value[1] = col_type(0, 0, 0, 0);
		value[2] = col_type(0, 0, 0, 0);
		value[3] = col_type(0, 0, 0, 0);
	}

	Matrix4x4::Matrix4x4(const Matrix4x4& m)
	{
		value[0] = m.value[0];
		value[1] = m.value[1];
		value[2] = m.value[2];
		value[3] = m.value[3];
	}

	Matrix4x4::Matrix4x4(const Vector4& v1, const Vector4& v2, const Vector4& v3, const Vector4& v4)
	{
		value[0] = v1;
		value[1] = v2;
		value[2] = v3;
		value[3] = v4;
	}

	Matrix4x4::Matrix4x4(
		float x1, float y1, float z1, float w1,
		float x2, float y2, float z2, float w2,
		float x3, float y3, float z3, float w3,
		float x4, float y4, float z4, float w4)
	{
		value[0] = col_type(x1, y1, z1, w1);
		value[1] = col_type(x2, y2, z2, w2);
		value[2] = col_type(x3, y3, z3, w3);
		value[3] = col_type(x4, y4, z4, w4);
	}

	Vector4& Matrix4x4::operator[](int i)
	{
		assert(i < 4 && i >= 0);
		return value[i];
	}

	const Vector4& Matrix4x4::operator[](int i) const
	{
		assert(i < 4 && i >= 0);
		return value[i];
	}

	Matrix4x4& Matrix4x4::operator=(const Matrix4x4& m)
	{
		value[0] = m[0];
		value[1] = m[1];
		value[2] = m[2];
		value[3] = m[3];
		return *this;
	}

	Matrix4x4 Matrix4x4::Transpose(Matrix4x4 mat)
	{
		Matrix4x4 result;
		result[0][0] = mat[0][0];
		result[0][1] = mat[1][0];
		result[0][2] = mat[2][0];
		result[0][3] = mat[3][0];

		result[1][0] = mat[0][1];
		result[1][1] = mat[1][1];
		result[1][2] = mat[2][1];
		result[1][3] = mat[3][1];

		result[2][0] = mat[0][2];
		result[2][1] = mat[1][2];
		result[2][2] = mat[2][2];
		result[2][3] = mat[3][2];

		result[3][0] = mat[0][3];
		result[3][1] = mat[1][3];
		result[3][2] = mat[2][3];
		result[3][3] = mat[3][3];

		return result;
	}

	Matrix4x4 operator+(const Matrix4x4& m1, const Matrix4x4& m2)
	{
		return Matrix4x4(
			m1[0] + m2[0],
			m1[1] + m2[1],
			m1[2] + m2[2],
			m1[3] + m2[3]);
	}

	Matrix4x4 operator-(const Matrix4x4& m1, const Matrix4x4& m2)
	{
		return Matrix4x4(
			m1[0] - m2[0],
			m1[1] - m2[1],
			m1[2] - m2[2],
			m1[3] - m2[3]);
	}

	Matrix4x4 operator*(const Matrix4x4& m, float scaler)
	{
		return Matrix4x4(
			m[0] * scaler,
			m[1] * scaler,
			m[2] * scaler,
			m[3] * scaler);
	}

	Matrix4x4 operator*(float scaler, const Matrix4x4& m)
	{
		return Matrix4x4(
			scaler * m[0],
			scaler * m[1],
			scaler * m[2],
			scaler * m[3]);
	}

	
}